Introduce an extra child of toplevel windows that serves to hold the focus
authorOwen Taylor <otaylor@redhat.com>
Wed, 18 Apr 2001 17:57:36 +0000 (17:57 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Wed, 18 Apr 2001 17:57:36 +0000 (17:57 +0000)
Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>

* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
  gdk/x11/gdkevents-x11.c: Introduce an extra child
of toplevel windows that serves to hold the focus to
avoid events being delivered to embedded windows.

* gdk/x11/gdkwindow-x11.c (gdk_window_new): Introduce
some extra variables to clean up code and reduce the
number of casts.

* gdk/x11/gdkwindow-x11.h (struct _GdkXPositionInfo): Use
guint for 1 bit bit fields, not gboolean.

ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/x11/gdkevents-x11.c
gdk/x11/gdkwindow-x11.c
gdk/x11/gdkwindow-x11.h

index 28f1c1f726b0d49437479844b1982f90d9e06222..1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
+         gdk/x11/gdkevents-x11.c: Introduce an extra child
+       of toplevel windows that serves to hold the focus to
+       avoid events being delivered to embedded windows.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Introduce
+       some extra variables to clean up code and reduce the
+       number of casts.
+
+       * gdk/x11/gdkwindow-x11.h (struct _GdkXPositionInfo): Use
+       guint for 1 bit bit fields, not gboolean.
+
 Wed Apr 18 10:04:23 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtktooltips.c (gtk_tooltips_paint_window): Return FALSE,
index 28f1c1f726b0d49437479844b1982f90d9e06222..1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629 100644 (file)
@@ -1,3 +1,17 @@
+Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
+         gdk/x11/gdkevents-x11.c: Introduce an extra child
+       of toplevel windows that serves to hold the focus to
+       avoid events being delivered to embedded windows.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Introduce
+       some extra variables to clean up code and reduce the
+       number of casts.
+
+       * gdk/x11/gdkwindow-x11.h (struct _GdkXPositionInfo): Use
+       guint for 1 bit bit fields, not gboolean.
+
 Wed Apr 18 10:04:23 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtktooltips.c (gtk_tooltips_paint_window): Return FALSE,
index 28f1c1f726b0d49437479844b1982f90d9e06222..1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629 100644 (file)
@@ -1,3 +1,17 @@
+Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
+         gdk/x11/gdkevents-x11.c: Introduce an extra child
+       of toplevel windows that serves to hold the focus to
+       avoid events being delivered to embedded windows.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Introduce
+       some extra variables to clean up code and reduce the
+       number of casts.
+
+       * gdk/x11/gdkwindow-x11.h (struct _GdkXPositionInfo): Use
+       guint for 1 bit bit fields, not gboolean.
+
 Wed Apr 18 10:04:23 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtktooltips.c (gtk_tooltips_paint_window): Return FALSE,
index 28f1c1f726b0d49437479844b1982f90d9e06222..1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629 100644 (file)
@@ -1,3 +1,17 @@
+Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
+         gdk/x11/gdkevents-x11.c: Introduce an extra child
+       of toplevel windows that serves to hold the focus to
+       avoid events being delivered to embedded windows.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Introduce
+       some extra variables to clean up code and reduce the
+       number of casts.
+
+       * gdk/x11/gdkwindow-x11.h (struct _GdkXPositionInfo): Use
+       guint for 1 bit bit fields, not gboolean.
+
 Wed Apr 18 10:04:23 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtktooltips.c (gtk_tooltips_paint_window): Return FALSE,
index 28f1c1f726b0d49437479844b1982f90d9e06222..1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629 100644 (file)
@@ -1,3 +1,17 @@
+Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
+         gdk/x11/gdkevents-x11.c: Introduce an extra child
+       of toplevel windows that serves to hold the focus to
+       avoid events being delivered to embedded windows.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Introduce
+       some extra variables to clean up code and reduce the
+       number of casts.
+
+       * gdk/x11/gdkwindow-x11.h (struct _GdkXPositionInfo): Use
+       guint for 1 bit bit fields, not gboolean.
+
 Wed Apr 18 10:04:23 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtktooltips.c (gtk_tooltips_paint_window): Return FALSE,
index 28f1c1f726b0d49437479844b1982f90d9e06222..1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629 100644 (file)
@@ -1,3 +1,17 @@
+Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
+         gdk/x11/gdkevents-x11.c: Introduce an extra child
+       of toplevel windows that serves to hold the focus to
+       avoid events being delivered to embedded windows.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Introduce
+       some extra variables to clean up code and reduce the
+       number of casts.
+
+       * gdk/x11/gdkwindow-x11.h (struct _GdkXPositionInfo): Use
+       guint for 1 bit bit fields, not gboolean.
+
 Wed Apr 18 10:04:23 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtktooltips.c (gtk_tooltips_paint_window): Return FALSE,
index 28f1c1f726b0d49437479844b1982f90d9e06222..1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629 100644 (file)
@@ -1,3 +1,17 @@
+Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
+         gdk/x11/gdkevents-x11.c: Introduce an extra child
+       of toplevel windows that serves to hold the focus to
+       avoid events being delivered to embedded windows.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Introduce
+       some extra variables to clean up code and reduce the
+       number of casts.
+
+       * gdk/x11/gdkwindow-x11.h (struct _GdkXPositionInfo): Use
+       guint for 1 bit bit fields, not gboolean.
+
 Wed Apr 18 10:04:23 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtktooltips.c (gtk_tooltips_paint_window): Return FALSE,
index bcb70be448a2ed92af39530b9f9907e96ca148d6..22eb7a31798362d77d524ccdf67eb15b6ab349cb 100644 (file)
@@ -404,6 +404,23 @@ gdk_check_wm_state_changed (GdkWindow *window)
     }
 }
 
+#define HAS_FOCUS(window_impl)                           \
+  ((window_impl)->has_focus || (window_impl)->has_pointer_focus)
+
+static void
+generate_focus_event (GdkWindow *window,
+                     gboolean   in)
+{
+  GdkEvent event;
+  
+  event.type = GDK_FOCUS_CHANGE;
+  event.focus_change.window = window;
+  event.focus_change.send_event = FALSE;
+  event.focus_change.in = in;
+  
+  gdk_event_put (&event);
+}
+
 static gint
 gdk_event_translate (GdkEvent *event,
                     XEvent   *xevent,
@@ -412,6 +429,7 @@ gdk_event_translate (GdkEvent *event,
   
   GdkWindow *window;
   GdkWindowObject *window_private;
+  GdkWindowImplX11 *window_impl = NULL;
   static XComposeStatus compose;
   KeySym keysym;
   int charcount;
@@ -439,12 +457,7 @@ gdk_event_translate (GdkEvent *event,
     }
   
   window = gdk_window_lookup (xevent->xany.window);
-  /* FIXME: window might be a GdkPixmap!!! */
-  
   window_private = (GdkWindowObject *) window;
-  
-  if (window != NULL)
-    gdk_window_ref (window);
 
   if (_gdk_moveresize_window &&
       (xevent->xany.type == MotionNotify ||
@@ -468,6 +481,29 @@ gdk_event_translate (GdkEvent *event,
         return FALSE;
     }
   
+  /* FIXME: window might be a GdkPixmap!!! */
+  if (window != NULL)
+    {
+      window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
+         
+      if (xevent->xany.window != GDK_WINDOW_XID (window))
+       {
+         g_assert (xevent->xany.window == window_impl->focus_window);
+
+         switch (xevent->type)
+           {
+           case KeyPress:
+           case KeyRelease:
+             xevent->xany.window = GDK_WINDOW_XID (window);
+             break;
+           default:
+             return False;
+           }
+       }
+
+      gdk_window_ref (window);
+    }
+
   event->any.window = window;
   event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
   
@@ -718,7 +754,20 @@ gdk_event_translate (GdkEvent *event,
                           xevent->xcrossing.window,
                           xevent->xcrossing.detail,
                           xevent->xcrossing.subwindow));
-      
+
+      /* Handle focusing (in the case where no window manager is running */
+      if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
+         xevent->xcrossing.detail != NotifyInferior &&
+         xevent->xcrossing.focus && !window_impl->has_focus)
+       {
+         gboolean had_focus = HAS_FOCUS (window_impl);
+         
+         window_impl->has_pointer_focus = TRUE;
+
+         if (HAS_FOCUS (window_impl) != had_focus)
+           generate_focus_event (window, TRUE);
+       }
+
       /* Tell XInput stuff about it if appropriate */
       if (window_private &&
          !GDK_WINDOW_DESTROYED (window) &&
@@ -792,6 +841,19 @@ gdk_event_translate (GdkEvent *event,
                           xevent->xcrossing.window,
                           xevent->xcrossing.detail, xevent->xcrossing.subwindow));
       
+      /* Handle focusing (in the case where no window manager is running */
+      if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
+         xevent->xcrossing.detail != NotifyInferior &&
+         xevent->xcrossing.focus && !window_impl->has_focus)
+       {
+         gboolean had_focus = HAS_FOCUS (window_impl);
+         
+         window_impl->has_pointer_focus = FALSE;
+
+         if (HAS_FOCUS (window_impl) != had_focus)
+           generate_focus_event (window, FALSE);
+       }
+
       event->crossing.type = GDK_LEAVE_NOTIFY;
       event->crossing.window = window;
       
@@ -853,38 +915,77 @@ gdk_event_translate (GdkEvent *event,
       
       break;
       
-    case FocusIn:
-    case FocusOut:
       /* We only care about focus events that indicate that _this_
        * window (not a ancestor or child) got or lost the focus
        */
-      switch (xevent->xfocus.detail)
+    case FocusIn:
+      GDK_NOTE (EVENTS,
+               g_message ("focus in:\t\twindow: %ld", xevent->xfocus.window));
+      
+      if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD)
        {
-       case NotifyAncestor:
-       case NotifyInferior:
-       case NotifyNonlinear:
-         GDK_NOTE (EVENTS,
-                   g_message ("focus %s:\t\twindow: %ld",
-                              (xevent->xany.type == FocusIn) ? "in" : "out",
-                              xevent->xfocus.window));
+         gboolean had_focus = HAS_FOCUS (window_impl);
          
+         switch (xevent->xfocus.detail)
+           {
+           case NotifyAncestor:
+           case NotifyNonlinear:
+           case NotifyVirtual:
+           case NotifyNonlinearVirtual:
+             window_impl->has_focus = TRUE;
+             break;
+           case NotifyPointer:
+             window_impl->has_pointer_focus = TRUE;
+             break;
+           case NotifyInferior:
+           case NotifyPointerRoot:
+           case NotifyDetailNone:
+             break;
+           }
+
+         if (HAS_FOCUS (window_impl) != had_focus)
+           generate_focus_event (window, TRUE);
+       }
+      break;
+    case FocusOut:
+      GDK_NOTE (EVENTS,
+               g_message ("focus out:\t\twindow: %ld", xevent->xfocus.window));
+
+      if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD)
+       {
+         gboolean had_focus = HAS_FOCUS (window_impl);
+           
+         switch (xevent->xfocus.detail)
+           {
+           case NotifyAncestor:
+           case NotifyNonlinear:
+           case NotifyVirtual:
+           case NotifyNonlinearVirtual:
+             window_impl->has_focus = FALSE;
+             break;
+           case NotifyPointer:
+             window_impl->has_pointer_focus = FALSE;
+           break;
+           case NotifyInferior:
+           case NotifyPointerRoot:
+           case NotifyDetailNone:
+             break;
+           }
+
+         if (HAS_FOCUS (window_impl) != had_focus)
+           generate_focus_event (window, FALSE);
+       }
+      break;
+
+#if 0      
          /* gdk_keyboard_grab() causes following events. These events confuse
           * the XIM focus, so ignore them.
           */
          if (xevent->xfocus.mode == NotifyGrab ||
              xevent->xfocus.mode == NotifyUngrab)
            break;
-         
-         event->focus_change.type = GDK_FOCUS_CHANGE;
-         event->focus_change.window = window;
-         event->focus_change.in = (xevent->xany.type == FocusIn);
+#endif
 
-         break;
-       default:
-         return_val = FALSE;
-       }
-      break;
-      
     case KeymapNotify:
       GDK_NOTE (EVENTS,
                g_message ("keymap notify"));
@@ -1381,6 +1482,11 @@ gdk_wm_protocols_filter (GdkXEvent *xev,
     }
   else if ((Atom) xevent->xclient.data.l[0] == gdk_wm_take_focus)
     {
+      GdkWindow *win = event->any.window;
+      Window focus_win = GDK_WINDOW_IMPL_X11(((GdkWindowObject *)win)->impl)->focus_window;
+
+      XSetInputFocus (GDK_WINDOW_XDISPLAY (win), focus_win,
+                     RevertToParent, xevent->xclient.data.l[1]);
     }
   else if ((Atom) xevent->xclient.data.l[0] == gdk_atom_intern ("_NET_WM_PING", FALSE))
     {
index 8daa3061ca34a85dcf0b36f3b0541178b6fcf90a..e48e83132af9ae84868f5618e274498634092e84 100644 (file)
@@ -171,6 +171,8 @@ gdk_window_impl_x11_finalize (GObject *object)
   if (!GDK_WINDOW_DESTROYED (wrapper))
     {
       gdk_xid_table_remove (draw_impl->xid);
+      if (window_impl->focus_window)
+       gdk_xid_table_remove (window_impl->focus_window);
     }
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -311,6 +313,8 @@ gdk_window_new (GdkWindow     *parent,
   GdkVisual *visual;
   Window xparent;
   Visual *xvisual;
+  Display *xdisplay;
+  Window xid;
 
   XSetWindowAttributes xattributes;
   long xattributes_mask;
@@ -342,7 +346,7 @@ gdk_window_new (GdkWindow     *parent,
   draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
   draw_impl->wrapper = GDK_DRAWABLE (window);
   
-  draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (parent); 
+  xdisplay = draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (parent); 
   
   private->parent = (GdkWindowObject *)parent;
 
@@ -489,15 +493,14 @@ gdk_window_new (GdkWindow     *parent,
       gdk_colormap_ref (draw_impl->colormap);
     }
 
-  draw_impl->xid = XCreateWindow (GDK_WINDOW_XDISPLAY (parent),
-                                  xparent,
-                                  impl->position_info.x, impl->position_info.y,
-                                  impl->position_info.width, impl->position_info.height,
-                                  0, depth, class, xvisual,
-                                  xattributes_mask, &xattributes);
+  xid = draw_impl->xid = XCreateWindow (xdisplay, xparent,
+                                       impl->position_info.x, impl->position_info.y,
+                                       impl->position_info.width, impl->position_info.height,
+                                       0, depth, class, xvisual,
+                                       xattributes_mask, &xattributes);
 
   gdk_drawable_ref (window);
-  gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
+  gdk_xid_table_insert (&draw_impl->xid, window);
   
   gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
                                  (attributes->cursor) :
@@ -509,13 +512,10 @@ gdk_window_new (GdkWindow     *parent,
   switch (GDK_WINDOW_TYPE (private))
     {
     case GDK_WINDOW_DIALOG:
-      XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
-                           GDK_WINDOW_XID (window),
-                           xparent);
+      XSetTransientForHint (xdisplay, xid, xparent);
     case GDK_WINDOW_TOPLEVEL:
     case GDK_WINDOW_TEMP:
-      XSetWMProtocols (GDK_WINDOW_XDISPLAY (window),
-                      GDK_WINDOW_XID (window),
+      XSetWMProtocols (xdisplay, xid,
                       gdk_wm_window_protocols, 3);
       break;
     case GDK_WINDOW_CHILD:
@@ -532,12 +532,30 @@ gdk_window_new (GdkWindow     *parent,
       
       return window;
     }
-  
+
+  if (class != InputOnly)
+    {
+      /* The focus window is off the visible area, and serves to receive key
+       * press events so they don't get sent to child windows.
+       */
+      impl->focus_window = XCreateSimpleWindow (xdisplay, xid,
+                                               -1, -1, 1, 1, 0,
+                                               xattributes.background_pixel,
+                                               xattributes.background_pixel);
+      /* FIXME: probably better to actually track the requested event mask for the toplevel
+       */
+      XSelectInput (xdisplay, impl->focus_window,
+                   KeyPressMask | KeyReleaseMask | FocusChangeMask);
+      
+      XMapWindow (xdisplay, impl->focus_window);
+      gdk_xid_table_insert (&impl->focus_window, window);
+    }
+
   size_hints.flags = PSize;
   size_hints.width = impl->width;
   size_hints.height = impl->height;
   
-  wm_hints.flags = InputHint | StateHint | WindowGroupHint;
+  wm_hints.flags = StateHint | WindowGroupHint;
   wm_hints.window_group = gdk_leader_window;
   wm_hints.input = True;
   wm_hints.initial_state = NormalState;
@@ -546,19 +564,14 @@ gdk_window_new (GdkWindow     *parent,
    * attention to PSize, and even if they do, is this the
    * correct value???
    */
-  XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
-                    GDK_WINDOW_XID (window),
-                    &size_hints);
+  XSetWMNormalHints (xdisplay, xid, &size_hints);
   
-  XSetWMHints (GDK_WINDOW_XDISPLAY (window),
-              GDK_WINDOW_XID (window),
-              &wm_hints);
+  XSetWMHints (xdisplay, xid, &wm_hints);
   
   if (!wm_client_leader_atom)
     wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
   
-  XChangeProperty (GDK_WINDOW_XDISPLAY (window),
-                  GDK_WINDOW_XID (window),
+  XChangeProperty (xdisplay, xid,
                   wm_client_leader_atom,
                   XA_WINDOW, 32, PropModeReplace,
                   (guchar*) &gdk_leader_window, 1);
@@ -575,9 +588,7 @@ gdk_window_new (GdkWindow     *parent,
       class_hint = XAllocClassHint ();
       class_hint->res_name = attributes->wmclass_name;
       class_hint->res_class = attributes->wmclass_class;
-      XSetClassHint (GDK_WINDOW_XDISPLAY (window),
-                    GDK_WINDOW_XID (window),
-                    class_hint);
+      XSetClassHint (xdisplay, xid, class_hint);
       XFree (class_hint);
     }
   
@@ -643,6 +654,8 @@ gdk_window_foreign_new (GdkNativeWindow anid)
 
   private->depth = attrs.depth;
   
+  _gdk_window_init_position (GDK_WINDOW (private));
+
   gdk_drawable_ref (window);
   gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
   
@@ -700,8 +713,12 @@ _gdk_windowing_window_destroy (GdkWindow *window,
 void
 gdk_window_destroy_notify (GdkWindow *window)
 {
+  GdkWindowImplX11 *window_impl;
+
   g_return_if_fail (window != NULL);
   
+  window_impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl);
+
   if (!GDK_WINDOW_DESTROYED (window))
     {
       if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
@@ -711,6 +728,9 @@ gdk_window_destroy_notify (GdkWindow *window)
     }
   
   gdk_xid_table_remove (GDK_WINDOW_XID (window));
+  if (window_impl->focus_window)
+    gdk_xid_table_remove (window_impl->focus_window);
+  
   gdk_drawable_unref (window);
 }
 
@@ -992,8 +1012,7 @@ gdk_window_reparent (GdkWindow *window,
   
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
-  g_return_if_fail (new_parent != NULL);
-  g_return_if_fail (GDK_IS_WINDOW (new_parent));
+  g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
   
   if (!new_parent)
     new_parent = gdk_parent_root;
index 76658b15c6d36099e8f18c16981a7360005ae8b1..0aaf0f93c2708c2609e43617f810d328b2d63825 100644 (file)
@@ -43,9 +43,9 @@ struct _GdkXPositionInfo
   gint height;
   gint x_offset;               /* Offsets to add to X coordinates within window */
   gint y_offset;               /*   to get GDK coodinates within window */
-  gboolean big : 1;
-  gboolean mapped : 1;
-  gboolean no_bg : 1;          /* Set when the window background is temporarily
+  guint big : 1;
+  guint mapped : 1;
+  guint no_bg : 1;             /* Set when the window background is temporarily
                                 * unset during resizing and scaling */
   GdkRectangle clip_rect;      /* visible rectangle of window */
 };
@@ -72,6 +72,22 @@ struct _GdkWindowImplX11
   gint height;
   
   GdkXPositionInfo position_info;
+
+  /* Set if the window, or any descendent of it, has the focus
+   */
+  guint has_focus : 1;
+
+  /* Set if !window_has_focus, but events are being sent to the
+   * window because the pointer is in it. (Typically, no window
+   * manager is running.
+   */
+  guint has_pointer_focus : 1;
+
+  /* We use an extra X window for toplevel windows that we XSetInputFocus()
+   * to in order to avoid getting keyboard events redirected to subwindows
+   * that might not even be part of this app
+   */
+  Window focus_window;
 };
  
 struct _GdkWindowImplX11Class